home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 23 / Amiga Format AFCD23 (Feb 1998, Issue 107).iso / +look_here_1st!+ / reader_requests / zkick301 / zkick.c < prev    next >
C/C++ Source or Header  |  1997-11-28  |  10KB  |  531 lines

  1. /*
  2.  
  3.     ZKick V3.01 -- Copyright (C) 1991 by Daniel Zenchelsky
  4.  
  5.         This program may be freely copied, as long as all copyright
  6.         notices are left intact and unchanged.
  7.  
  8. */
  9.  
  10. #include <stdio.h>
  11. #include "zkick.h"
  12.  
  13. #include <libraries/configvars.h>
  14. #include <libraries/expansion.h>
  15. #include <exec/types.h>
  16. #include <exec/memory.h>
  17. #include <exec/tasks.h>
  18. #include <exec/execbase.h>
  19.  
  20. #define BUFSIZE     (64*1024)
  21. #define KICKSIZE     (512*1024)
  22. #define NUMBUFS     (KICKSIZE/BUFSIZE)
  23.  
  24. #define STARTKICK    (void *)0x200000
  25.  
  26. #define STACK_SIZE 1024
  27.  
  28. #define BOGUSMMU    0xffffffffL
  29.  
  30. #define IFDEBUG if (DEBUG) {
  31. #define ENDIFDEBUG }
  32.  
  33. #define USAGE1 "Usage: ZKick [-start <hex address>] [-debug] [-die] [-mmu]\n"
  34. #define USAGE2 "             [-noreset] [-nochecksum] [-print] [-c0] KickFile\n"
  35.  
  36. /* For the Assembly routines to use: */
  37.  
  38. long NumBufs=NUMBUFS;
  39. ULONG BufSize=BUFSIZE;
  40. ULONG EndKick;
  41.  
  42. extern ULONG StartKick;
  43.  
  44. APTR stack = NULL;
  45. struct Task *tc = NULL;
  46. char *taskname = "Zkick Task";
  47.  
  48. struct ExpansionBase *ExpansionBase=NULL;
  49. struct ExecBase *ExecBase=NULL;
  50.  
  51. void main();
  52. void cleanup();
  53. void DoAddCD();
  54. void GetMem();
  55. void KickLoad();
  56. void StartTask();
  57. extern void KickCopy();
  58. extern void MakeRomTag();
  59. extern long GetCPUType();
  60. extern long GetMMUType();
  61. extern long connum;
  62. extern struct ConfigDev config[8];
  63. extern long memnum;
  64. extern ULONG memory[8][2];
  65. extern long Survive;
  66. extern long MMU;
  67. extern long NOMMU;
  68. extern long NORESET;
  69. extern long NOCHECKSUM;
  70. extern long DEBUG;
  71. extern long PRINT;
  72. extern long LOADC0;
  73. extern long V175;
  74. long CPU;
  75.  
  76. int CXBRK(void) { return(0); }  
  77.  
  78. void *MemArray[NUMBUFS];
  79.  
  80. void main(argc,argv)
  81. int argc;
  82. char *argv[];
  83. {
  84.     struct ConfigDev *MyConfigDev;
  85.     char *kickfile;
  86.  
  87.     printf("ZKick V3.01 Copyright (C) 1991 by Daniel Zenchelsky\n");
  88.     printf("---------------------------------------------------\n");
  89.     printf("      This program may be freely copied, as long\n");
  90.     printf("      as all copyright notices are left intact.\n\n");
  91.  
  92.     ExpansionBase= (struct ExpansionBase *)OpenLibrary( EXPANSIONNAME,0);
  93.     if(ExpansionBase==NULL)
  94.     {
  95.         printf("Error opening expansion library!!\n");
  96.         cleanup();
  97.     }
  98.  
  99.     ExecBase= (struct ExecBase *)OpenLibrary("exec.library",0);
  100.     if(ExecBase==NULL)
  101.     {
  102.         printf("Error opening Exec library!!\n");
  103.         cleanup();
  104.     }
  105.  
  106.     if (ExecBase->LibNode.lib_Version<33 || ExecBase->LibNode.lib_Version>34)
  107.     {
  108.         printf("ZKick will only run under Kickstart 1.2/1.3\n");
  109.         cleanup();
  110.     }
  111.  
  112.     connum=0;    
  113.  
  114.     argv++;
  115.     argc--;
  116.  
  117.     Survive=1;
  118.     NOMMU=1;
  119.     StartKick=0x200000;
  120.  
  121.     if (argc<1)
  122.     {
  123.         printf(USAGE1);
  124.         printf(USAGE2);
  125.         cleanup();
  126.     }
  127.  
  128.     while(argc>1)
  129.     {
  130.         if (argv[0][0]!='-')
  131.         {
  132.             printf(USAGE1);
  133.             printf(USAGE2);
  134.             cleanup();
  135.         }
  136.  
  137.         if (strcmp("-die",argv[0])==0)
  138.         {
  139. IFDEBUG
  140.             printf("-die\n");
  141. ENDIFDEBUG
  142.             Survive=0;
  143.         }
  144.  
  145.         if (strcmp("-mmu",argv[0])==0)
  146.         {
  147. IFDEBUG
  148.             printf("-mmu\n");
  149. ENDIFDEBUG
  150.             NOMMU=0;
  151.         }
  152.  
  153.         if (strcmp("-noreset",argv[0])==0)
  154.         {
  155. IFDEBUG
  156.             printf("-noreset\n");
  157. ENDIFDEBUG
  158.             NORESET=1;
  159.         }
  160.  
  161.         if (strcmp("-nochecksum",argv[0])==0)
  162.         {
  163. IFDEBUG
  164.             printf("-nochecksum\n");
  165. ENDIFDEBUG
  166.             NOCHECKSUM=1;
  167.         }
  168.  
  169.         if (strcmp("-start",argv[0])==0)
  170.         {
  171.             sscanf(argv[1]," %x",&StartKick);
  172. IFDEBUG
  173.             printf("-start %x\n",StartKick);
  174. ENDIFDEBUG
  175.  
  176.             if (StartKick<0x200000)
  177.             {
  178.                 printf("Can't put kickstart in CHIP ram.\n");
  179.                 cleanup();
  180.             }
  181.  
  182.             if (V175==0)
  183.             {
  184.                 printf("-start only works with Kickstart 37.175, see docs\n");
  185.                 cleanup();
  186.             }
  187.  
  188.             argv++;
  189.             argc--;
  190.         }
  191.  
  192.         if (strcmp("-debug",argv[0])==0)
  193.         {
  194.             printf("-debug\n");
  195.             DEBUG=1;
  196.         }
  197.  
  198.         if (strcmp("-print",argv[0])==0)
  199.         {
  200. IFDEBUG
  201.             printf("-print\n");
  202. ENDIFDEBUG
  203.             PRINT=1;
  204.         }
  205.  
  206.         if (strcmp("-c0",argv[0])==0)
  207.         {
  208.  
  209. IFDEBUG
  210.             printf("-c0\n");
  211. ENDIFDEBUG
  212.  
  213.             if (V175==0)
  214.             {
  215.                 printf("-c0 only works with Kickstart 37.175, see docs\n");
  216.                 cleanup();
  217.             }
  218.  
  219.             if (((ULONG)ExecBase&0xFFFF0000)==0x00C00000)
  220.             {
  221.                 printf("ExecBase is in $C00000 memory.\n");
  222.                 printf("Run NoC0Ram before using ZKick.\n");
  223.                 cleanup();
  224.             }
  225.  
  226.             LOADC0=1;
  227.             StartKick=0x00C00000;
  228.         }
  229.  
  230.         if (strcmp("-v175",argv[0])==0)
  231.         {
  232. IFDEBUG
  233.             printf("-v175\n");
  234. ENDIFDEBUG
  235.             V175=1;
  236.             printf("Kickstart relocation enabled.  Be sure you are using V37.175!\n");
  237.         }
  238.  
  239.         argv++;
  240.         argc--;
  241.     }
  242.  
  243.     kickfile=argv[0];
  244.     EndKick=StartKick+KICKSIZE-1;
  245.  
  246.     if((stack = (APTR) AllocMem(STACK_SIZE, MEMF_CHIP | MEMF_CLEAR)) == NULL)
  247.     {
  248.          printf("Not enough memory for task stack\n");
  249.         cleanup();
  250.     }
  251.  
  252.     if ((tc = (struct Task *)
  253.         AllocMem(sizeof(struct Task),MEMF_CHIP | MEMF_CLEAR | MEMF_PUBLIC)) == NULL)
  254.     {
  255.         printf("Not enough memory for task structure\n");
  256.         cleanup();
  257.     }
  258.  
  259.     if (LOADC0==0 && CheckForMem()==-1)
  260.     {
  261.         printf("You must have a 512k or greater memory board at $%x.\n",StartKick);
  262.         cleanup();
  263.     }
  264.  
  265.     MyConfigDev=NULL;
  266.  
  267.     MyConfigDev=FindConfigDev(NULL,-1,-1);
  268.     
  269.     if(MyConfigDev==NULL) printf("No configured devices found\n");
  270.         else DoAddCD(MyConfigDev);
  271.  
  272.     while((MyConfigDev=FindConfigDev(MyConfigDev,-1,-1))!=NULL)
  273.     {
  274.         DoAddCD(MyConfigDev);
  275.     }
  276.  
  277.     printf("Found %d expansion devices, and %d memory boards.\n",connum,memnum);
  278.  
  279.     if (NOMMU==0)
  280.     {
  281.  
  282.         CPU=GetCPUType();
  283.         MMU=GetMMUType();
  284.  
  285.         if (MMU==BOGUSMMU) MMU=0;
  286.  
  287. IFDEBUG
  288.         printf("CPU: %d, MMU: %d\n",CPU,MMU);
  289. ENDIFDEBUG
  290.     }
  291.     
  292.     if (LOADC0==0) GetMem();
  293.     KickLoad(kickfile);
  294.  
  295.     MakeRomTag();
  296.     printf("Rebooting in 5 seconds...\n");
  297.     Delay(50*5);
  298.     StartTask();
  299.  
  300.     Wait(0L);        /* Hang around forever (not very long, actually.) */
  301. }
  302.  
  303. void cleanup()
  304. {
  305.     if(tc) FreeMem((void *)tc,sizeof(struct Task));
  306.     if(stack) FreeMem((void *)stack,(ULONG)STACK_SIZE);
  307.     if(ExpansionBase) CloseLibrary(ExpansionBase);
  308.     if(ExecBase) CloseLibrary(ExecBase);
  309.     exit(0);
  310. }
  311.  
  312. void DoAddCD(dev)
  313. struct ConfigDev *dev;
  314. {
  315.     if ((dev->cd_Rom.er_Type & ERTF_MEMLIST) == 0)
  316.     {
  317.         if (connum<8)
  318.         {
  319.     
  320.             config[connum]=*dev;
  321.             config[connum].cd_Rom.er_Reserved0c=0;
  322.             config[connum].cd_Rom.er_Reserved0d=0;
  323.             config[connum].cd_Rom.er_Reserved0e=0;
  324.             config[connum].cd_Rom.er_Reserved0f=0;
  325.             config[connum].cd_Flags |= CDF_CONFIGME;
  326.             config[connum].cd_Driver=NULL;
  327.  
  328.             connum++;
  329.  
  330. IFDEBUG
  331.         printf("Adding board at $%x to list.\n",(ULONG)(dev->cd_BoardAddr));
  332. ENDIFDEBUG
  333.         }
  334.             else
  335.         {
  336.             printf("Too many expansion boards!\n");
  337.             cleanup();
  338.         }
  339.     }
  340.         else
  341.     {
  342.  
  343.         if (memnum<7)
  344.         {
  345.  
  346.             ULONG start,len,end;
  347.  
  348.             start=(ULONG)dev->cd_BoardAddr;
  349.             len=(ULONG)dev->cd_BoardSize;
  350.             end=start+len-1;
  351.  
  352.             if ((INTERSECT(StartKick,EndKick,start,end) && !SUBSET(StartKick,EndKick,start,end)) || SUPERSET(StartKick,EndKick,start,end))
  353.             {
  354.                 printf("Kickstart memory can not span multiple memory boards!\n");
  355.                 cleanup();
  356.             }
  357.  
  358.             if (SUBSET(StartKick,EndKick,start,end) || EQUAL(StartKick,EndKick,start,end))
  359.             {
  360.                 
  361.                 if (start<StartKick)
  362.                 {
  363.                     memory[memnum][0]=start;
  364.                     memory[memnum][1]=StartKick-start;
  365.  
  366. IFDEBUG
  367.                     printf("Adding memory at $%x, size $%x to list.\n",
  368.                         memory[memnum][0],memory[memnum][1]);
  369. ENDIFDEBUG
  370.                     memnum++;
  371.  
  372.                 }
  373.  
  374.                 if (end>EndKick)
  375.                 {
  376.                     memory[memnum][0]=EndKick+1;
  377.                     memory[memnum][1]=end-EndKick;
  378.  
  379. IFDEBUG
  380.                     printf("Adding memory at $%x, size $%x to list.\n",
  381.                         memory[memnum][0],memory[memnum][1]);
  382. ENDIFDEBUG
  383.                     memnum++;
  384.  
  385.                 }
  386.  
  387.             }
  388.                 else
  389.                 {
  390.                     memory[memnum][0]=start;
  391.                     memory[memnum][1]=len;
  392.  
  393.                     memnum++;
  394.                 }
  395.  
  396.         }
  397.             else
  398.         {
  399.             printf("Too many memory boards!\n");
  400.             cleanup();
  401.         }
  402.     }
  403. }
  404.  
  405. /* Allocate NUMBUFS (8) buffers of size BUFSIZE (64k) _NOT_ within the final
  406.    KickStart address region.  
  407. */
  408.  
  409. void GetMem()
  410. {
  411.     int BufNum,BadNum=0,x;
  412.     void *MemBad[NUMBUFS];
  413.  
  414.     for (BufNum=0;BufNum<NUMBUFS;BufNum++)
  415.     {
  416.         MemArray[BufNum]=(void *)AllocMem(BUFSIZE,0);
  417.         while (MemArray[BufNum]!=(void *)NULL && 
  418.             !ABOVE((ULONG)MemArray[BufNum],(ULONG)MemArray[BufNum]+BUFSIZE-1,StartKick,EndKick) &&
  419.             !BELOW((ULONG)MemArray[BufNum],(ULONG)MemArray[BufNum]+BUFSIZE-1,StartKick,EndKick))
  420.         {
  421.             MemBad[BadNum++]=MemArray[BufNum];    
  422. IFDEBUG
  423.             printf("* UNUSED * Memory allocated at location $%x\n",(ULONG)MemBad[BadNum-1]);
  424. ENDIFDEBUG
  425.             MemArray[BufNum]=(void *)AllocMem(BUFSIZE,0);
  426.         }
  427.         if (MemArray[BufNum]==(void *)NULL)
  428.         {
  429.             if (BufNum>0)
  430.                 for (x=0;x<BufNum-1;x++) FreeMem(MemArray[x],BUFSIZE);
  431.             if (BadNum>0)
  432.                 for (x=0;x<BadNum-1;x++) FreeMem(MemBad[x],BUFSIZE);
  433.             printf("Couldn't allocate memory.\n");
  434.             cleanup();
  435.         }
  436. IFDEBUG
  437.         printf("Memory allocated at location $%x\n",(ULONG)MemArray[BufNum]);
  438. ENDIFDEBUG
  439.     }
  440.  
  441. /* Free memory that was allocated inside KickStart area */
  442.  
  443.     if (BadNum>0)
  444.         for (x=0;x<BadNum-1;x++) FreeMem(MemBad[x],BUFSIZE);
  445.  
  446. }
  447.  
  448. void KickLoad(filename)
  449. char filename[];
  450. {
  451.     int BufNum;
  452.     int file;
  453.  
  454.     file=open(filename,0);
  455.  
  456.     if (file==-1)
  457.     {
  458.         printf("Error opening %s\n",filename);
  459.         for (BufNum=0;BufNum<NUMBUFS;BufNum++) FreeMem(MemArray[BufNum],(ULONG)BUFSIZE);
  460.         close(filename);
  461.         cleanup();
  462.     }
  463.  
  464.     lseek(file,8,0);
  465.  
  466.     if (LOADC0!=0)
  467.     {
  468. IFDEBUG
  469.         printf("Loading Kickstart @ %08x\n",StartKick);
  470. ENDIFDEBUG
  471.  
  472.         if (read(file,(void *)StartKick,KICKSIZE)!=KICKSIZE)
  473.         {
  474.             printf("Error reading %s\n",filename);
  475.             for (BufNum=0;BufNum<NUMBUFS;BufNum++) FreeMem(MemArray[BufNum],(ULONG)BUFSIZE);
  476.             close(filename);
  477.             cleanup();
  478.         }
  479.     }
  480.         else
  481.     {
  482.         for (BufNum=0;BufNum<NUMBUFS;BufNum++)
  483.         {
  484. IFDEBUG
  485.             printf("Reading %d\n",BufNum*BUFSIZE);
  486. ENDIFDEBUG
  487.             if (read(file,MemArray[BufNum],BUFSIZE)!=BUFSIZE)
  488.             {
  489.                 printf("Error reading %s\n",filename);
  490.                 for (BufNum=0;BufNum<NUMBUFS;BufNum++) FreeMem(MemArray[BufNum],(ULONG)BUFSIZE);
  491.                 close(filename);
  492.                 cleanup();
  493.             }
  494.         }
  495.     }
  496. }
  497.  
  498. void StartTask()
  499. {
  500.     /* Initialize necessary fields, others were cleared by MEMF_CLEAR */
  501.     tc->tc_Node.ln_Type = NT_TASK;
  502.     tc->tc_Node.ln_Name = taskname;
  503.     tc->tc_SPLower = (APTR)stack;
  504.     tc->tc_SPUpper = (APTR)(STACK_SIZE + (ULONG)stack);
  505.     tc->tc_SPReg   = tc->tc_SPUpper;
  506.  
  507.     AddTask(tc, KickCopy, 0L);
  508. }
  509.  
  510. #define FUDGEFACTOR 64    /* Fudge factor for MemHeader */
  511.  
  512. CheckForMem()
  513. {
  514.    struct MemHeader  *mem;
  515.    BOOL flag=FALSE;
  516.  
  517.    Forbid();
  518.    for (mem = (struct MemHeader *)ExecBase->MemList.lh_Head;
  519.         mem->mh_Node.ln_Succ;
  520.         mem = (struct MemHeader *)mem->mh_Node.ln_Succ)
  521.     {
  522.         if (((ULONG) (mem->mh_Lower - FUDGEFACTOR ) <= StartKick) && ((ULONG) mem->mh_Upper >= EndKick))
  523.             flag=TRUE;
  524.     }
  525.    Permit();
  526.  
  527.    if (flag==TRUE) return(0);
  528.     else return(-1);
  529. }
  530.  
  531.